import asyncio
from common.utility import Utility

async def say_after(content: str, delay: int = 1) -> None:
    Utility.print_info(f'entered. It will delay {delay} seconds.')
    await asyncio.sleep(delay)
    Utility.print_info(content)
    Utility.print_info('exited.')

async def asyncio_wait_for(timeout: int|float=2):
    try:
        await asyncio.wait_for(say_after('wait for test', 2), timeout)
    except TimeoutError as err:
        Utility.print_info(f'caught a timeout error: {err}')

async def asyncio_wait(timeout: int|float = 2, return_when: str = asyncio.ALL_COMPLETED):
    tasks: list = [asyncio.create_task(say_after('hello 1', 1)),
                   asyncio.create_task(say_after('hello 2', 2)),
                   asyncio.create_task(say_after('hello 3', 3))]
    done,pending = await asyncio.wait(tasks, timeout=timeout, return_when=return_when)
    for d in done:
        print(d)
    for p in pending:
        print(p)

async def asyncio_as_completed(timeout: int|float = 2):
    tasks: list = [say_after('hello 1', 1), say_after('hello 2', 2), say_after('hello 3', 3)]
    for task in asyncio.as_completed(tasks, timeout=timeout):
        try:
            await task
        except TimeoutError as err:
            Utility.print_info(f'caught a timeout error: {err}')

asyncio.run(asyncio_wait_for(1))
asyncio.run(asyncio_wait_for(3))
asyncio.run(asyncio_wait(2, asyncio.FIRST_COMPLETED))
asyncio.run(asyncio_wait(4, asyncio.ALL_COMPLETED))asyncio_timeout.py
asyncio.run(asyncio_wait(2, asyncio.FIRST_EXCEPTION))
asyncio.run(asyncio_as_completed())